﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Umbraco.Cms.Web;
using System.Web.Mvc;
using System.IO;
using Filesystem.FilePicker.Models;
using System.Text.RegularExpressions;

namespace Filesystem.FilePicker.Controllers
{
    public class FilePickerExplorerController : Controller
    {
        public bool IsLogin
        {
            get
            {
                var ticket = HttpContext.GetUmbracoAuthTicket();
                return ticket != null && !ticket.Expired;
            }
        }

        public ActionResult Index() 
        {
            return Content("");
        }

        public JsonResult CreateFolder()
        {
            if (!IsLogin)
                return Json(new { success = false });
            string parent = Request["parent"];
            string name = Request["name"];
            if (string.IsNullOrEmpty(name))
            {
                return Json(new { success = false, msg = "The folder name cannot be empty." }, JsonRequestBehavior.AllowGet);
            }
            var regExp = new Regex(@"^(?!^(PRN|AUX|CLOCK\$|NUL|CON|COM\d|LPT\d|\..*)(\..+)?$)");
            if (!regExp.IsMatch(name))
            {
                return Json(new { success = false, msg = "The folder name is not correct." }, JsonRequestBehavior.AllowGet);
            }
            if (string.IsNullOrEmpty(parent))
                parent = "/";
            string parentPath = Server.MapPath(parent);
            if (!Directory.Exists(parentPath))
            {
                return Json(new { success = false, msg = "Parent folder does not exist." }, JsonRequestBehavior.AllowGet);
            }
            if (!parentPath.EndsWith("\\"))
                parentPath += "\\";
            string newFolderPath = parentPath + name;
            if (Directory.Exists(newFolderPath))
            {
                return Json(new { success = false, msg = "The folder already exists" }, JsonRequestBehavior.AllowGet);
            }
            try
            {
                Directory.CreateDirectory(newFolderPath);
            }
            catch
            {
                return Json(new { success = false, msg = "An error has occurred while creating the folder." }, JsonRequestBehavior.AllowGet);
            }
            return Json(new { success = true }, JsonRequestBehavior.AllowGet);
        }

        public JsonResult GetFiles()
        {
            if (!IsLogin)
                return Json(new { }, JsonRequestBehavior.AllowGet);
            string root = Request["root"];
            if (string.IsNullOrEmpty(root))
                root = "/";
            if (!root.StartsWith("/") || !root.StartsWith("\\"))
                root = "/" + root;
            string rootPath = Server.MapPath(root);
            string ext = Request["ext"];
            rootPath = (new DirectoryInfo(rootPath)).FullName;
            if (!rootPath.EndsWith("\\"))
                rootPath += "\\";
            string workFolder = "";
            string currentFile = Request["file"];
            string currentFolder = Request["folder"];
            if (string.IsNullOrEmpty(currentFolder))
                currentFolder = "";
            if (string.IsNullOrEmpty(currentFolder))
            {
                if (string.IsNullOrEmpty(currentFile))
                    workFolder = rootPath;
                else
                    workFolder = Path.GetDirectoryName(rootPath + currentFile);
            }
            else
                workFolder = rootPath + currentFolder;
            if (!workFolder.EndsWith("\\"))
                workFolder += "\\";

            List<FileFolderModel> resultList = new List<FileFolderModel>();
            
            DirectoryInfo dirInfo = new DirectoryInfo(workFolder);
            if (workFolder != rootPath)
            {
                FileFolderModel parent = new FileFolderModel();
                parent.Name = "..";
                parent.IsFolder = true;
                parent.Size = "";
                parent.CreateDate = dirInfo.Parent.CreationTime.ToString("yyyy-MM-dd hh:mm:ss");
                string parentPath = dirInfo.Parent.FullName + "\\";
                parent.Path = parentPath.Replace(rootPath, "").Replace("\\", "/");
                resultList.Add(parent);
            }
            DirectoryInfo[] dirs = dirInfo.GetDirectories();
            if (dirs != null && dirs.Length > 0)
            {
                foreach (var item in dirs)
                {
                    FileFolderModel folderItem = new FileFolderModel();
                    folderItem.Name = item.Name;
                    folderItem.Size = "";
                    folderItem.IsFolder = true;
                    folderItem.CreateDate = item.CreationTime.ToString("yyyy-MM-dd hh:mm:ss");
                    folderItem.Path = item.FullName.Replace(rootPath, "").Replace("\\","/");
                    resultList.Add(folderItem);
                }
            }
            FileInfo[] files = dirInfo.GetFiles();
            if (files != null && files.Length > 0)
            {
                foreach (var item in files)
                {
                    if (".config,.exe,.dll,.aspx.ashx,.cs.ascx,.asmx,.db,.mdf,.sdf,.pdb".Contains(item.Extension.ToLower()))
                    {
                        continue;
                    }
                    if (!string.IsNullOrEmpty(ext) && !ext.ToLower().Contains(item.Extension.ToLower()))
                        continue;
                    FileFolderModel fileItem = new FileFolderModel();
                    fileItem.Name = item.Name;
                    double length = item.Length/1024;
                    fileItem.Size = length.ToString() + "KB";
                    fileItem.IsFolder = false;
                    fileItem.CreateDate = item.CreationTime.ToString("yyyy-MM-dd hh:mm:ss");
                    fileItem.Path = item.FullName.Replace(rootPath, "").Replace("\\","/");
                    resultList.Add(fileItem);
                }
            }
            currentFolder = workFolder.Replace(rootPath, "").Replace("\\", "/");
            if (currentFolder.EndsWith("/"))
                currentFolder = currentFolder.TrimEnd('/');
            return Json(new { success = true, folder = currentFolder, data = resultList.ToArray() }, JsonRequestBehavior.AllowGet);
        }

        [HttpPost]
        public ActionResult UploadFile()
        {
            if (Request.Files.Count < 1)
                return Content("0");
            string folder = Request.QueryString["folder"];
            if (string.IsNullOrEmpty(folder))
                folder = "/";
            string folderPath = Server.MapPath(folder);
            if (!folderPath.EndsWith("\\"))
                folderPath += "\\";
            if (!Directory.Exists(folderPath))
                return Content("0");
            string filePath = folderPath + Request.Files[0].FileName;
            string ext = Path.GetExtension(filePath).ToLower();
            if (ext == ".dll" || ext == ".config")
                return Content("0");
            Request.Files[0].SaveAs(filePath);
            return Content("1");
        }

        public ActionResult FileUploadWindow()
        {
            if (!IsLogin)
            {
                Response.StatusCode = 404;
                Response.SubStatusCode = 0;
                Response.StatusDescription = "The page your are looking for are not found";
                return null;
            }
            var view = View();
            view.ViewName = "/App_Plugins/Packages/FilePicker/Views/FileUploadWindow.cshtml";
            return view;
        }
    }
}
